-- Key to Notes.applescript
-- Key to Notes

(*
 * Copyright (c) 2007, Enrico Franchi and Marco Balestra
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 * 1) Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 2) Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * 3) Neither my name nor the names of its contributors may be used to
 * endorse or promote products derived from this software without specific
 * prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *)

--  Created by Riko on 25/09/07.
--  Copyright 2007 

global theApplication
global theSlideshow

on should quit after last window closed theObject
	(*Add your script here.*)
end should quit after last window closed

on opened theObject
	initializeWindow()
end opened

on action theObject
	if theObject is popup button "appchooser" of window 1 then
		set theApplication to title of popup button "appchooser" of window 1
		log theApplication
	end if
end action

on clicked theObject
	set theButton to ""
	tell window of theObject
		if theObject is equal to button "quitButton" of box 1 then
			quit
		else if theObject is equal to button "loadButton" of box 1 then
			my loadButtonClicked()
		else if theObject is equal to button "extractButton" of box 1 then
			my extractButtonClicked()
		else if theObject is equal to button "currentButton" of box 1 then
			my currentButtonClicked()
		end if
	end tell
end clicked

on initializeWindow()
	tell menu of popup button "appchooser" of window 1
		make new menu item at the end of menu items with properties {title:"BBEdit", enabled:true}
		make new menu item at the end of menu items with properties {title:"TextEdit", enabled:true}
		make new menu item at the end of menu items with properties {title:"TextMate", enabled:true}
		set theApplication to title of first item of menu items
		log theApplication
	end tell
end initializeWindow


on currentButtonClicked()
	try
		closeAnnoyingDialog(application "Keynote")
		tell application "Keynote" to set thePresentation to slideshow of window 1
		set theSlideshow to thePresentation
	on error
		set theReply to (display dialog "Keynote has no opened document, do you want to choose one?" buttons {"Cancel", "Open..."})
		set theAnswer to button returned of theReply
		if theAnswer is equal to "Open..." then
			loadButtonClicked()
		else
			return
		end if
	end try
	loadDocument()
end currentButtonClicked


on loadButtonClicked()
	set theFile to chooseKNfile()
	tell application "Keynote"
		open theFile
		set theSlideshow to slideshow of window 1
	end tell
	loadDocument()
end loadButtonClicked

on extractButtonClicked()
	try
		set theData to getKNnotes(theSlideshow)
	on error
		display dialog ("You did not select any Keynote file.") attached to window 1 buttons {"Ok"}
		return
	end try
	if theApplication is equal to "Pages" then
		writePagesDocument(theData)
	else if theApplication is equal to "TextEdit" then
	    writeTextEditDocument(theData)
	else
		display dialog ("Support for application " & theApplication & " has not been added yet.") attached to window 1 buttons {"Ok"}
		return
	end if
end extractButtonClicked

on loadDocument()
	tell application "Keynote" to set theTitle to name of theSlideshow
	set title of window 1 to theTitle
	try
		tell application "Keynote" to set thePath to path of theSlideshow
		set image of image view "imageView" of window 1 to load image thePath & "/QuickLook/Thumbnail.jpg"
	on error
		display dialog "Unable to load preview."
	end try
end loadDocument

(*
 * getKNfile prompts the user for a Keynote file.
 * If the chosen file is not a Keynote file, it prompts the user
 * again
 *)
on chooseKNfile()
	repeat while true
		set foo to (choose file with prompt "Choose a keynote file" of type {"????"} without invisibles)
		set bar to foo as text
		if bar ends with ".key:" then return foo
		display dialog "This isn't a valid Keynote file!"
	end repeat
end chooseKNfile

(*
 * getKNfile returns the currently opened Keynote file, if any.
 * Otherwise it calls chooseKNfile to prompt the user for one
 *)
on getKNfile()
	try
		set keynoteDoc to path of document of window 1 of application "Keynote"
		keynoteDoc
		tell application "Keynote" to set thePresentation to slideshow 1
	on error
		tell application "Keynote" to close window 1
		set theFile to chooseKNfile()
		tell application "Keynote"
			open theFile
			set thePresentation to slideshow 1
		end tell
	end try
	return thePresentation
end getKNfile

(*
 * getKNnotes gets the presenter notes from thePresentation
 * it returns a dictionary with keys notes and titles.
 * the value of the notes key is an "array" of notes (one for each slide)
 * the value of the titles key is an array of titles
 *)
on getKNnotes(thePresentation)
	set myNotes to {}
	set myTitles to {}
	set ret to {notes:missing value, titles:missing value}
	
	tell application "Keynote"
		repeat with theSLIDE in slides of thePresentation
			tell theSLIDE
				if not skipped then
					set the end of myNotes to notes
					set the end of myTitles to title
				end if
			end tell
		end repeat
	end tell
	set notes of ret to myNotes
	set titles of ret to myTitles
	return ret
end getKNnotes

(*
 * writePagesDocument creates a new Pages document with myData
 * myData should be a dictionary like the one returned by getKNnotes
 *)
on writePagesDocument(myData)
	set myNotes to notes of myData
	set myTitles to titles of myData
	
	closeAnnoyingDialog(application "Pages")
	tell application "Pages"
		make new document at front with properties {name:"Slides Notes"}
		tell body text of document 1
			repeat with theIndex from 1 to length of myNotes
				make new text at end with data (item theIndex of myTitles & return & return) with properties {paragraph style:"Heading"}
				make new text at end with data (item theIndex of myNotes & return) with properties {paragraph style:"Body Bullet"}
				make new text at end with data (return & return) with properties {paragraph style:"Body"}
			end repeat
		end tell
	end tell
end writePagesDocument

(*
 * writeTextEditDocument creates a new TextEdit document with myData
 * myData should be a dictionary like the one returned by getKNnotes
 *)

on writeTextEditDocument(myData)
    set myNotes to notes of myData
	set myTitles to titles of myData
	
	tell app "TextEdit"
	   	make new document at front with properties {name:"Slides Notes"}
		tell text of document 1
			repeat with theIndex from 1 to length of myNotes
				make new paragraph at end with data (item theIndex of myTitles & return & return) with properties {size : 18}
				make new paragraph at end with data (item theIndex of myNotes & return) with properties {}
				make new paragraph at end with data (return & return) with properties {}
			end repeat
		end tell
	end tell
	
end writeTextEditDocument

(* closeAnnoyingDialog should close the annoying dialog that iWork 2008
 * applications present when no document is open
 *)
on closeAnnoyingDialog(theApplication)
	try
		set hasWindow to document of window 1 of theApplication
		hasWindow
	on error
		return
	end try
	try
		set firstWindowDoc to path of document of window 1 of theApplication
		firstWindowDoc
	on error
		tell theApplication to close window 1
	end try
end closeAnnoyingDialog
